package com.huixuebao.settle.service.impl;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.huixuebao.common.bean.ApiResult;
import com.huixuebao.common.bean.ResponseData;
import com.huixuebao.common.enumeration.ResultCodeEnum;
import com.huixuebao.settle.dto.*;
import com.huixuebao.settle.entity.*;
import com.huixuebao.settle.mapper.*;
import com.huixuebao.settle.service.InsureOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
public class InsureOrderServiceImpl implements InsureOrderService {

    @Autowired
    private InsuredOrderMapper insuredOrderMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private MechanismMapper mechanismMapper;

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private FileMapper  fileMapper;

    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    RedisTemplate redisTemplate;

    @Override
    public ResponseData submitOrder(OrderDTO dto) throws ParseException {
        ResponseData responseData = new ResponseData();

        HeadDTO headDTO = dto.getHead();
        InsuredOrderEntity insuredOrder = new InsuredOrderEntity();
        InsObjectDTO insObjectDTO = dto.getBody().getInsObject();
        String mid = insObjectDTO.getMechanismId();
        MechanismEntity mechanismInfo=mechanismMapper.selectById(mid);
        int maxCountOfMechaism =Integer.parseInt(mechanismInfo.getInsureRestrict());
        String mKey=getMechanismKeyOrTime(mid,1);
        String mKeyTime = getMechanismKeyOrTime(mid,0);


        if(redisTemplate.opsForValue().increment(mKey).intValue()>maxCountOfMechaism){
            mechanismInfo.setState("0");
            mechanismMapper.updateById(mechanismInfo);
            responseData.setCode(ResultCodeEnum.FAILURE.getCode());
            responseData.setErrorMessage("当前机构次数超限，请下个月在投保!!");
            return  responseData;
        }
        redisTemplate.expire(mKey,Integer.parseInt(mKeyTime), TimeUnit.DAYS);
        log.info("机构key："+mKey+"，过期时间："+redisTemplate.getExpire(mKey,TimeUnit.DAYS)+",当月次数："+redisTemplate.opsForValue().get(mKey));
        insuredOrder.getInsuredRelation();

        /**
         * 机构信息
         */
        ExtendInfoDTO extendInfoDTO = dto.getBody().getInsObject().getExtendInfos();

        SimpleDateFormat dsf = new SimpleDateFormat("yyyy-MM-dd");
        StudentEntity studentEntity = new StudentEntity();
        // 被保人
        InsuredDTO insuredDTO = dto.getBody().getInsured();
        UserEntity insuredPerson = new UserEntity();
        String insuredRelation = insuredDTO.getInsuredRelation();
        if(insuredRelation.equals("01")){
            log.info("insuredRelation = 01{}:" + "01被保人可为空");
            insuredOrder.setInsuredRelation(insuredDTO.getInsuredRelation());
            if(StrUtil.isNotEmpty(insuredDTO.getInsuredName())){
                /**
                 * 生成id
                 */
                insuredPerson.setId(insuredOrder.getInsuredPersonId());
                /**
                 * 创建时间
                 */
                insuredPerson.setCreateTime(new DateTime());
                /**
                 * 被保人证件类型
                 */
                insuredPerson.setType(Integer.valueOf(insuredDTO.getInsuredIdType()));
                /**
                 * 被保人姓名
                 */
                insuredPerson.setName(insuredDTO.getInsuredName());
                /**
                 * 被被保人证件号
                 */
                String insuredIdNo = insuredDTO.getInsuredIdNo();
                int countId = userMapper.selectCount(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getCid,insuredIdNo));
                if (countId > 0) {
                    log.info("当前用户Cid已经存在！");
                }else {
                    insuredPerson.setCid(insuredDTO.getInsuredIdNo());
                }
                /**
                 * 被被保人证件生效时间
                 */
                String insuredIdStartTime = insuredDTO.getInsuredIdStartTime();
                if (StrUtil.isNotEmpty(insuredIdStartTime)){
                    insuredPerson.setStartTime(dsf.parse(insuredDTO.getInsuredIdStartTime()));
                }else {
                    insuredPerson.setStartTime(null);
                }
                /**
                 * 被被保人证件结束时间
                 */
                 String insuredIdEndTime = insuredDTO.getInsuredIdEndTime();
                if (StrUtil.isNotEmpty(insuredIdEndTime)){
                    insuredPerson.setEndTime(dsf.parse(insuredDTO.getInsuredIdEndTime()));
                }else {
                    insuredPerson.setEndTime(null);
                }
                /**
                 * 被保人电话
                 */
                insuredPerson.setPhone(insuredDTO.getInsuredPhone());
                /**
                 * 被保人邮箱
                 */
                insuredPerson.setMail(insuredDTO.getInsuredMail());
                /**
                 * 被保人国籍
                 */
                insuredPerson.setNationality(insuredDTO.getInsuredNationality());
                /**
                 * 被保人职业/行也
                 */
                insuredPerson.setProfession(insuredDTO.getInsuredProfessional());
                /**
                 * 被保人地址
                 */
                insuredPerson.setAddress(insuredDTO.getAddress());
                int insuredCount = userMapper.selectCount(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getCid, insuredDTO.getInsuredIdNo()));
                if (insuredCount > 0) {
                    userMapper.update(insuredPerson, new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getCid, insuredDTO.getInsuredIdNo()));
                } else {
                    userMapper.insert(insuredPerson);
                }
            }
        }else {
            /**
             * 生成id
             */
            insuredPerson.setId(insuredOrder.getInsuredPersonId());

            insuredOrder.setInsuredRelation(insuredDTO.getInsuredRelation());
            /**
             * 创建时间
             */
            insuredPerson.setCreateTime(new DateTime());
            /**
             * 被保人证件类型
             */
            insuredPerson.setType(Integer.valueOf(insuredDTO.getInsuredIdType()));
            /**
             * 被保人姓名
             */
            insuredPerson.setName(insuredDTO.getInsuredName());
            /**
             * 被被保人证件号
             */
            String insuredIdNo = insuredDTO.getInsuredIdNo();
            int countId = userMapper.selectCount(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getCid,insuredIdNo));
            if (countId > 0) {
                log.info("当前用户Cid已经存在！");
            }else {
                insuredPerson.setCid(insuredDTO.getInsuredIdNo());
            }
            /**
             * 被被保人证件生效时间
             */
            String insuredIdStartTime = insuredDTO.getInsuredIdStartTime();
            if (StrUtil.isNotEmpty(insuredIdStartTime)){
                insuredPerson.setStartTime(dsf.parse(insuredDTO.getInsuredIdStartTime()));
            }else {
                insuredPerson.setStartTime(null);
            }
            /**
             * 被被保人证件结束时间
             */
            String insuredIdEndTime = insuredDTO.getInsuredIdEndTime();
            if (StrUtil.isNotEmpty(insuredIdEndTime)){
                insuredPerson.setEndTime(dsf.parse(insuredDTO.getInsuredIdEndTime()));
            }else {
                insuredPerson.setEndTime(null);
            }
            /**
             * 被保人电话
             */
            insuredPerson.setPhone(insuredDTO.getInsuredPhone());
            /**
             * 被保人邮箱
             */
            insuredPerson.setMail(insuredDTO.getInsuredMail());
            /**
             * 被保人国籍
             */
            insuredPerson.setNationality(insuredDTO.getInsuredNationality());
            /**
             * 被保人职业/行也
             */
            insuredPerson.setProfession(insuredDTO.getInsuredProfessional());
            /**
             * 被保人地址
             */
            insuredPerson.setAddress(insuredDTO.getAddress());
            int insuredCount = userMapper.selectCount(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getCid, insuredDTO.getInsuredIdNo()));
            if (insuredCount > 0) {
                userMapper.update(insuredPerson, new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getCid, insuredDTO.getInsuredIdNo()));
            } else {
                userMapper.insert(insuredPerson);
            }
        }
        // 投保人
        HolderDTO holderDTO = dto.getBody().getHolder();
        UserEntity holderPerson = new UserEntity();
        holderPerson.setId(insuredOrder.getHolderPersonId());
        holderPerson.setCreateTime(new DateTime());
        /**
         * 投保人姓名
         */
        holderPerson.setName(holderDTO.getHolderName());
        holderPerson.setType(Integer.valueOf(holderDTO.getHolderIdType()));
        /**
         * 投保人证件号
         */
        String holderIdNo = holderDTO.getHolderIdNo();
        int countId = userMapper.selectCount(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getCid,holderIdNo));
        if (countId > 0) {
            log.info("当前用户Cid已经存在！");
        }else {
            holderPerson.setCid(holderDTO.getHolderIdNo());
        }
        /**
         * 证件号生效时间: yyyy­MM­dd
         */
        String holderIdStartTime = holderDTO.getHolderIdStartTime();
        if (StrUtil.isNotEmpty(holderIdStartTime)) {
            holderPerson.setStartTime(dsf.parse(holderDTO.getHolderIdStartTime()));
        }else {
            holderPerson.setStartTime(null);
        }
        /**
         * 证件号终止时间: yyyy­MM­dd
         */

        String holderIdEndTime = holderDTO.getHolderIdEndTime();
        if (StrUtil.isNotEmpty(holderIdEndTime)) {
            holderPerson.setEndTime(dsf.parse(holderDTO.getHolderIdEndTime()));
        }else {
            holderPerson.setEndTime(null);
        }
        /**
         * 投保人电话
         */
        holderPerson.setPhone(holderDTO.getHolderPhone());
        /**
         * 投保人邮箱
         */
        holderPerson.setMail(holderDTO.getHolderMail());
        /**
         * 投保人国籍
         */
        holderPerson.setNationality(holderDTO.getHolderNationality());
        /**
         * 投保人职业/行业
         */
        holderPerson.setProfession(holderDTO.getHolderProfessional());
        int holderCount = userMapper.selectCount(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getCid, holderDTO.getHolderIdNo()));
        if (holderCount > 0) {
            userMapper.update(holderPerson, new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getCid, holderDTO.getHolderIdNo()));
        } else {
            userMapper.insert(holderPerson);
        }
        /**
          * 机构学生
        */
        studentEntity.setId(IdUtil.simpleUUID());
        studentEntity.setStudentType(Integer.valueOf(extendInfoDTO.getStudentType()));
        studentEntity.setStudentName(extendInfoDTO.getStudentName());
        studentEntity.setStudentIdType(extendInfoDTO.getStudentIdType());
        studentEntity.setProject(extendInfoDTO.getEducationalProject());
        studentEntity.setLearningModality(extendInfoDTO.getLearningModality());
        studentEntity.setStudentIdNo(extendInfoDTO.getStudentIdNo());
        /**
         * 学生表中插入机构id
         */
        studentEntity.setMechanismId(extendInfoDTO.getEducationalId());
        int studentNo = studentMapper.selectCount(new LambdaQueryWrapper<StudentEntity>().eq(StudentEntity::getStudentIdNo,extendInfoDTO.getStudentIdNo()));
        if (studentNo > 0) {
            studentEntity.setUpdateTime(new DateTime());
            studentMapper.update(studentEntity, new LambdaQueryWrapper<StudentEntity>().eq(StudentEntity::getStudentIdNo,extendInfoDTO.getStudentIdNo()));
        } else {
            studentEntity.setCreateTime(new DateTime());
            studentMapper.insert(studentEntity);
        }
        // 保单

        insuredOrder.setId(IdUtil.simpleUUID());
        /**
         * 产品代码
         */
        insuredOrder.setProductCode(headDTO.getProductCode());
        /**
         * 出单类型 proposal: 核保 insure：出单 cancel：退保
         */
        insuredOrder.setInsureType(headDTO.getInsureType());
        /**
         * 投保（签单时间）时 间：yyyy­MM­dd HH:mm:ss
         */
        insuredOrder.setApplyTime(dsf.parse(headDTO.getApplyTime()));
        /**
         * 被投保人id
         */
        insuredOrder.setInsuredPersonId(insuredPerson.getId());
        /**
         * 投保人id
         */
        insuredOrder.setHolderPersonId(holderPerson.getId());
        /**
         * 保险份数（整数）
         */
        insuredOrder.setInsureCount(Integer.valueOf(insObjectDTO.getInsureCount()));
        /**
         * 总保费，无小数点， 单位：分
         */
        insuredOrder.setTotalPremium(insObjectDTO.getTotalPremium());
        /**
         * 总保额，无小数点， 单位：分
         */
        insuredOrder.setTotalAmount(insObjectDTO.getTotalAmount());
        /**
         * 起保日期（生效 日）：yyyy­MM­dd HH:mm:ss
         */
        insuredOrder.setEffectiveStartTime(dsf.parse(insObjectDTO.getEffectiveStartTime()));
        /**
         * 终保日期：yyyy­ MM­dd HH:mm:ss
         */
        insuredOrder.setEffectiveEndTime(dsf.parse(insObjectDTO.getEffectiveEndTime()));
        /**
         * 课程id
         */
        insuredOrder.setCourseId(insObjectDTO.getCourseId());
        /**
         * 机构id
         */
        insuredOrder.setMechanismId(insObjectDTO.getMechanismId());
        /**
         * 订单号，唯一， 24位以内的数字
         */
        insuredOrder.setOrderId(headDTO.getOrderId());
        /**
         * 投保人类型(1­个 人；2­企业)，如果 是用户自行投保请传 1
         */
        insuredOrder.setHolderType(holderDTO.getHolderType());
        /**
         * 将订单信息的设定默认值0
         */
        Integer settleState = 0;
        insuredOrder.setSettleState(settleState);
        insuredOrder.setCreateTime(new DateTime());
        insuredOrder.setStudentId(studentEntity.getId());
        int orderId = insuredOrderMapper.selectCount(new LambdaQueryWrapper<InsuredOrderEntity>().eq(InsuredOrderEntity::getOrderId, headDTO.getOrderId()));
        if (orderId > 0) {
            insuredOrderMapper.update(insuredOrder, new LambdaQueryWrapper<InsuredOrderEntity>().eq(InsuredOrderEntity::getOrderId, headDTO.getOrderId()));
        } else {
            insuredOrderMapper.insert(insuredOrder);
        }

        MechanismEntity mechanismEntity = new MechanismEntity();
        /**
         * 省
         */
        mechanismEntity.setProvince(insObjectDTO.getProvince());
        /**
         * 城市
         */
        mechanismEntity.setCity(insObjectDTO.getCity());
        mechanismEntity.setName(extendInfoDTO.getEducationalName());
        mechanismEntity.setIdType(extendInfoDTO.getEducationalIdType());
        mechanismEntity.setBusinessLicens(extendInfoDTO.getEducationalId());
        mechanismEntity.setAddress(extendInfoDTO.getEducationalAddress());
        int mechanismId = mechanismMapper.selectCount(new LambdaQueryWrapper<MechanismEntity>().eq(MechanismEntity::getId,extendInfoDTO.getEducationalId()));
        if (mechanismId > 0) {
            //mechanismMapper.update(mechanismEntity, new LambdaQueryWrapper<MechanismEntity>().eq(MechanismEntity::getId,extendInfoDTO.getEducationalId()));
        } else {
            //mechanismMapper.insert(mechanismEntity);
        }
        // 合同文件地址
        List<String> contractFiles = extendInfoDTO.getEducationalContract();
        for (String contract : contractFiles) {
            FileEntity fileEntity = new FileEntity();
            fileEntity.setId(IdUtil.simpleUUID());
            fileEntity.setOrderId(headDTO.getOrderId());
            fileEntity.setPath(contract);
            fileEntity.setCreateTime(new DateTime());
            fileEntity.setFileType("CONTRACT");
            fileMapper.insert(fileEntity);
        }
        // 课程表文件地址
        List<String> scheduleFiles = extendInfoDTO.getEducationalSchedule();
        for (String schedule : scheduleFiles) {
            FileEntity fileEntity = new FileEntity();
            fileEntity.setId(IdUtil.simpleUUID());
            fileEntity.setOrderId(headDTO.getOrderId());
            fileEntity.setPath(schedule);
            fileEntity.setCreateTime(new DateTime());
            fileEntity.setFileType("SCHEDULE");
            fileMapper.insert(fileEntity);
        }
        responseData.setCode(ResultCodeEnum.SUCCESS.getCode());
        responseData.setMessage("提交订单成功!!");
        return responseData;
    }

    private String getMechanismKeyOrTime(String mechanismId,int type) {
        Calendar cal = Calendar.getInstance();
        int currentYear = cal.get(Calendar.YEAR);
        int currentMonth = cal.get(Calendar.MONTH)+1;
        int currentDay = cal.get(Calendar.DAY_OF_MONTH);
        int maxDays =cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        String result = "";
        if(type==1){
            result = mechanismId + currentYear +""+currentMonth;
        }else{
            result = (maxDays-currentDay + 1)+"";
        }
        return result;
    }


    @Override
    public void updateOrder(InsureOrderDTO dto) {
        InsuredOrderEntity insuredOrder = new InsuredOrderEntity();
        insuredOrder.setOrderId(dto.getProposalId());
        insuredOrder.setPolicyId(dto.getPolicyNo());
        insuredOrder.setOrderState(Integer.valueOf(dto.getPolicyStatus()));
        insuredOrder.setApplyTime(DateUtil.parseDateTime(dto.getTimestamp()));
        insuredOrder.setPolicyUrl(dto.getPolicyUrl());
        insuredOrderMapper.update(insuredOrder, new LambdaQueryWrapper<InsuredOrderEntity>()
                .eq(InsuredOrderEntity::getOrderId, dto.getProposalId()));
    }

    /**
     * 根据用户userId查询用户保单
     *
     * @param phone
     */
    @Override
    public List<InsuredOrderEntity> listInsuredOrders(String phone) {
        List<UserEntity> users = userMapper.selectList(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getPhone, phone));
        List<InsuredOrderEntity> result = new ArrayList<>();
        if (CollUtil.isNotEmpty(users)) {
            List<String> userIds = users.stream().map(UserEntity::getId).collect(Collectors.toList());
            result = insuredOrderMapper.selectList(new LambdaQueryWrapper<InsuredOrderEntity>()
                    .in(InsuredOrderEntity::getInsuredPersonId, userIds)
                    .or()
                    .in(InsuredOrderEntity::getHolderPersonId, userIds));
        }
       return result;
    }

    /**
     * 根据用户policyId更新保单状态
     *
     * @param policyId
     */
    @Override
    public ApiResult updateSettleState(String policyId, String settleState) {
        ApiResult apiResult = new ApiResult();
        insuredOrderMapper.update(null, new LambdaUpdateWrapper<InsuredOrderEntity>()
                .eq(InsuredOrderEntity::getPolicyId, policyId)
                .set(InsuredOrderEntity::getSettleState, settleState));
        apiResult.setSuccess(true);
        return apiResult;
    }
}